package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.OrderReportVO;
import com.sky.vo.SalesTop10ReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class ReportServiceimpl implements ReportService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Override
    public TurnoverReportVO Turnover(LocalDate start, LocalDate end) {
        //存放指定日期
        List<LocalDate> listTime=getLocalDates(start,end);
        //存营业额的
        StringBuilder sb = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        for (int i = 0; i < listTime.size(); i++) {
            sb.append(listTime.get(i));
            //因为orderTime是一个datetime所以需要传入一个开始和结束时间
            Map map = new HashMap<>();
            map.put("begin",LocalDateTime.of(listTime.get(i), LocalTime.MIN));
            map.put("end",LocalDateTime.of(listTime.get(i),LocalTime.MAX));
            map.put("status",Orders.COMPLETED);
            Double a = orderMapper.sumbydate(map);
            a =( a == null ? 0.0 : a);
            sb2.append(a);
            if(i!=listTime.size()-1) {
                sb.append(",");
                sb2.append(",");
            }
        }
        return new TurnoverReportVO(sb.toString(),sb2.toString());
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> listTime=getLocalDates(begin,end);
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        StringBuilder sb3 = new StringBuilder();
        for (int i = 0; i < listTime.size(); i++) {
            sb1.append(listTime.get(i));
            Map map = new HashMap<>();
            map.put("end",LocalDateTime.of(listTime.get(i),LocalTime.MAX));
            Integer userallnumber =userMapper.countbyMap(map) ;
            map.put("begin",LocalDateTime.of(listTime.get(i), LocalTime.MIN));
            Integer usernewnumber = userMapper.countbyMap(map);
            userallnumber = (userallnumber == null ?0:userallnumber);
            usernewnumber = (usernewnumber == null ?0:usernewnumber);
            sb2.append(userallnumber);
            sb3.append(usernewnumber);
            if(i!=listTime.size()-1) {
                sb1.append(",");
                sb2.append(",");
                sb3.append(",");
            }
        }
        return new UserReportVO(sb1.toString(), sb2.toString() , sb3.toString());
    }

    @Override
    public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> listTime=getLocalDates(begin,end);
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        StringBuilder sb3 = new StringBuilder();
        Integer sum1=0,sum2=0;
        for (int i = 0; i < listTime.size(); i++) {
            sb1.append(listTime.get(i));
            LocalDateTime endtime = LocalDateTime.of(listTime.get(i), LocalTime.MAX);
            LocalDateTime starttime = LocalDateTime.of(listTime.get(i), LocalTime.MIN);
            Integer status = Orders.COMPLETED;
            Integer orderallnumber = getcountorder(starttime,endtime,null);
            Integer ordernewnumber =  getcountorder(starttime,endtime,status);
            sb2.append(orderallnumber);
            sum1+=orderallnumber;
            sb3.append(ordernewnumber);
            sum2+=ordernewnumber;
            if(i!=listTime.size()-1) {
                sb1.append(",");
                sb2.append(",");
                sb3.append(",");
            }
        }
        double lv = (double) sum2 /sum1;
        return new OrderReportVO(sb1.toString(), sb2.toString(), sb3.toString(),sum1 ,sum2,lv);
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        List <GoodsSalesDTO> getcount = orderDetailMapper.getcount(LocalDateTime.of(begin, LocalTime.MAX),LocalDateTime.of(end, LocalTime.MIN));
        List<String> name = getcount.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        List<Integer> number = getcount.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        return new SalesTop10ReportVO(StringUtils.join(name,","),StringUtils.join(number,","));
    }

    private Integer getcountorder(LocalDateTime start, LocalDateTime end,Integer status){
        Map map = new HashMap<>();
        map.put("end",end);
        map.put("begin",start);
        map.put("status",status);
        Integer c = orderMapper.getcountbymap(map);
        c = c==null?0:c;
        return c;
    }

    private List<LocalDate> getLocalDates(LocalDate start, LocalDate end) {
        List<LocalDate> listTime= new ArrayList<>();
        do {
            listTime.add(start);
            start = start.plusDays(1);
        }while (!end.equals(start));
        return listTime;
    }
    
}
